//
// Copyright (c) 2011 Alex Nesterenko
//

#include "nane/WindowSystem/X11/X11Window.h"

namespace nane
{
    ////////////////////////////////////////////////////////////////////////////////////////////////
    X11Window::X11Window( Display* _display, Window _hWindow, Atom _deleteAtom )
        : m_display( _display )
        , m_hWindow( _hWindow )
        , m_deleteAtom( _deleteAtom )
    {

    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    X11Window::~X11Window()
    {

    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void X11Window::handleEvent( const XEvent& _event )
    {
        switch( _event.type )
        {
            case ClientMessage:
                if( _event.xclient.format == 32 && _event.xclient.data.l[0] == static_cast<long>(m_deleteAtom) )    // window is about to close
                {
                    onClose();
                }
                break;
            case DestroyNotify:
                onClose();
                break;
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void X11Window::onClose()
    {
        if( m_handler != NULL )
            m_handler->onClose();
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    IWindow::OSHandle X11Window::getOSHandle()
    {
        return reinterpret_cast<IWindow::OSHandle>(m_hWindow);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void X11Window::show()
    {
        XWindowAttributes attributes;
        XGetWindowAttributes(m_display, m_hWindow, &attributes);
        XMapWindow(m_display, m_hWindow);
        XMoveWindow(m_display, m_hWindow, attributes.x, attributes.y);
        XFlush(m_display);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void X11Window::updateMessages()
    {
        XEvent event;
        while( XCheckWindowEvent(m_display, m_hWindow, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event) )
        {
            handleEvent(event);
        }

        // The ClientMessage event does not appear under any Event Mask
        while( XCheckTypedWindowEvent(m_display, m_hWindow, ClientMessage, &event) )
        {
            handleEvent(event);
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void X11Window::setMessageHandler( IWindowMessageHandler* _handler )
    {
        m_handler = _handler;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
}   // namespace nane
